package main

import "fmt"

// Visitor 定义访问者接口
type Visitor interface {
	VisitText(text *Text)
	VisitImage(image *Image)
	VisitTable(table *Table)
}

// Element 定义元素接口
type Element interface {
	Accept(visitor Visitor)
}

// Text 是具体元素：文本
type Text struct {
	content string
}

func (t *Text) Accept(visitor Visitor) {
	visitor.VisitText(t)
}

// Image 是具体元素：图片
type Image struct {
	src string
}

func (i *Image) Accept(visitor Visitor) {
	visitor.VisitImage(i)
}

// Table 是具体元素：表格
type Table struct {
	rows int
	cols int
}

func (t *Table) Accept(visitor Visitor) {
	visitor.VisitTable(t)
}

// PDFExportVisitor 是具体访问者：导出为 PDF
type PDFExportVisitor struct{}

func (p *PDFExportVisitor) VisitText(text *Text) {
	fmt.Printf("Exporting text to PDF: %s\n", text.content)
}

func (p *PDFExportVisitor) VisitImage(image *Image) {
	fmt.Printf("Exporting image to PDF: %s\n", image.src)
}

func (p *PDFExportVisitor) VisitTable(table *Table) {
	fmt.Printf("Exporting table to PDF: %d rows, %d cols\n", table.rows, table.cols)
}

// HTMLExportVisitor 是具体访问者：导出为 HTML
type HTMLExportVisitor struct{}

func (h *HTMLExportVisitor) VisitText(text *Text) {
	fmt.Printf("Exporting text to HTML: %s\n", text.content)
}

func (h *HTMLExportVisitor) VisitImage(image *Image) {
	fmt.Printf("Exporting image to HTML: %s\n", image.src)
}

func (h *HTMLExportVisitor) VisitTable(table *Table) {
	fmt.Printf("Exporting table to HTML: %d rows, %d cols\n", table.rows, table.cols)
}

// Document 是对象结构
type Document struct {
	elements []Element
}

func (d *Document) AddElement(element Element) {
	d.elements = append(d.elements, element)
}

func (d *Document) Accept(visitor Visitor) {
	for _, element := range d.elements {
		element.Accept(visitor)
	}
}

func main() {
	// 创建文档对象
	document := &Document{}

	// 添加元素
	document.AddElement(&Text{content: "Hello, World!"})
	document.AddElement(&Image{src: "image.png"})
	document.AddElement(&Table{rows: 3, cols: 2})

	// 创建访问者
	pdfVisitor := &PDFExportVisitor{}
	htmlVisitor := &HTMLExportVisitor{}

	// 导出为 PDF
	fmt.Println("Exporting to PDF:")
	document.Accept(pdfVisitor)

	// 导出为 HTML
	fmt.Println("\nExporting to HTML:")
	document.Accept(htmlVisitor)
}
